package com.changgou.seckill.task;

import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Set;

@Component
public class SeckillGoodsPushTask {
  // 注入dao
  @Autowired private SeckillGoodsMapper seckillGoodsMapper;
  @Autowired private RedisTemplate redisTemplate;

  /** * 商品定时存入rdeis 5秒 */
  @Scheduled(cron = "0/5 * * * * ?")
  public void loadSecKillGoodsToRedis() {

    // 求时间菜单
    List<Date> dateMenus = DateUtil.getDateMenus();

    // 循环查询每个时间区间的秒杀商品
    for (Date dateMenu : dateMenus) {
      // 时间的字符串的格式
      String timespace = "SeckillGoods_" + DateUtil.date2Str(dateMenu);
      // 构建查询秒杀商品的条件
      Example example = new Example(SeckillGoods.class);
      Example.Criteria criteria = example.createCriteria();
      // 1.必须是审核的商品
      criteria.andEqualTo("status", "1");
      // 2. 库存必须大于0
      criteria.andGreaterThan("stockCount", 0);
      // 3.时间菜单的时间=<start_time && end.time<时间菜单的开始时间+2
      criteria.andGreaterThanOrEqualTo("startTime", dateMenu);
      // 商品的结束时间end.time<时间菜单的开始时间+2
      criteria.andLessThan("endTime", DateUtil.addDateHour(dateMenu, 2));


      // 排除已经存入到redis中的数据
      Set keys = redisTemplate.boundHashOps(timespace).keys();
      if (keys != null && keys.size() > 0) {
        criteria.andNotIn("id", keys);
      }
      // 查询商品秒杀数据
      List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectByExample(example);
      // 循环商品数据
      for (SeckillGoods seckillGood : seckillGoods) {
        // 把数据存入到redis中
        redisTemplate.boundHashOps(timespace).put(seckillGood.getId(), seckillGood);
        // 解决商品超卖问题 给每个商品做个队列
        redisTemplate.boundListOps("SeckillGoodsCountList_"+seckillGood.getId()).leftPushAll(putAlls(seckillGood.getStockCount(),seckillGood.getId()));
      }
    }
    // Hu
  }

  /**
   * 获取每个商品的集合
   * @param stockCount
   * @param id
   * @return
   */
  public  Long[] putAlls(Integer stockCount,Long id){
    Long[] ids = new Long[stockCount];
    // 循环这个商品的库存数据就是 ids[1]=112121,ids[2]=112121
    for (int i = 0; i < ids.length; i++) {
      //
      ids[i]=id;
    }
    return  ids;
  }
}
